package com.github.aloxc.plugin.restplus.navigator;


import com.github.aloxc.plugin.DonotGuard;
import com.github.aloxc.plugin.restplus.common.Consts;
import com.github.aloxc.plugin.restplus.entity.RestConfig;
import com.github.aloxc.plugin.restplus.listener.RefreshListener;
import com.github.aloxc.plugin.restplus.utils.ToolkitUtil;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;
import java.net.URL;
/**
 *
 * @author leero
 */
@DonotGuard
public class RestServicesNavigator implements  ProjectComponent {
    public static final String TOOL_WINDOW_ID = "RestPlus";

    private RestConfig config;
    private final Project myProject;

    public Project getProject() {
        return myProject;
    }

    private JTree myTree;
    protected RestServiceStructure myStructure;
    private ToolWindowEx myToolWindow;

    private RestServiceProjectsManager myProjectsManager;

    public RestServicesNavigator(Project myProject,RestServiceProjectsManager projectsManager) {
//        super(myProject);
        this.myProject = myProject;
        config = RestConfig.loadConfig(myProject);
        myProjectsManager = projectsManager;
    }

    public JTree getUrlTree() {
        return myTree;
    }

    public RestConfig getConfig() {
        return config;
    }

    public void setConfig(RestConfig config) {
        this.config = config;
    }

    public RestServiceStructure getRestServiceStructure() {
        return myStructure;
    }

    private void initTree() {

        myTree = new JTree();
        myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
    }

    @Override
    public void initComponent() {
        listenForProjectsChanges();
        ToolkitUtil.runWhenInitialized(myProject, () -> {
            if (myProject.isDisposed()) {
                return;
            }
            initToolWindow();
//            initConfig();
        });
    }

    /**
     * 初始化配置文件
     */
    private void initConfig() {
//        new RestConfig().init();
    }

    private void initToolWindow() {

        final ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(myProject);
        myToolWindow = (ToolWindowEx)manager.getToolWindow(TOOL_WINDOW_ID);
        if(myToolWindow != null) {return;}

        initTree();
        DefaultTreeModel model = (DefaultTreeModel) myTree.getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
        root.removeAllChildren();
        model.reload(root);


        myToolWindow = (ToolWindowEx)manager.registerToolWindow(TOOL_WINDOW_ID, false, ToolWindowAnchor.RIGHT, myProject, true);
        myToolWindow.setIcon(Consts.Icons.SERVICE);
        JPanel panel = new RestServicesNavigatorPanel(myProject, myTree);

        final ContentFactory contentFactory = ServiceManager.getService(ContentFactory.class);
        final Content content = contentFactory.createContent(panel, "", false);
        ContentManager contentManager = myToolWindow.getContentManager();
        contentManager.addContent(content);
        contentManager.setSelectedContent(content, false);


        final ToolWindowManagerListener listener = new ToolWindowManagerListener() {
            boolean wasVisible = false;

            @Override
            public void stateChanged() {
                if (myToolWindow.isDisposed()) {
                    return;
                }
                boolean visible = myToolWindow.isVisible();
                if (!visible || wasVisible) {
                    return;
                }
                scheduleStructureUpdate();
                wasVisible = true;
            }
        };
        this.myProject.getMessageBus().connect(myProject).subscribe(ToolWindowManagerListener.TOPIC, listener);
        new RefreshListener(myProject).doRefreshProject();
//        manager.addToolWindowManagerListener(listener, myProject);
        //todo: 扩展 toolWindows 右键
//        ActionManager actionManager = ActionManager.getInstance();
//        DefaultActionGroup group = new DefaultActionGroup();
//        group.add(actionManager.getAction("Maven.GroupProjects"));
//        group.add(actionManager.getAction("Maven.ShowIgnored"));
//        group.add(actionManager.getAction("Maven.ShowBasicPhasesOnly"));
//        group.add(actionManager.getAction("Maven.AlwaysShowArtifactId")); // 默认显示 app serviceName
//        group.add(actionManager.getAction("Maven.ShowVersions")); //
//        myToolWindow.setAdditionalGearActions(group);
    }

    public void scheduleStructureUpdate() {
        scheduleStructureRequest(() -> myStructure.update());

    }
    private void scheduleStructureRequest(final Runnable r) {

        if (myToolWindow == null) {
            return;
        }

//        ToolkitUtil.invokeLater(myProject, () -> {
//        ToolkitUtil.runWhenInitialized(myProject, () -> {
        ToolkitUtil.runWhenProjectIsReady(myProject, () -> {
            if (!myToolWindow.isVisible()) {
                return;
            }

            boolean shouldCreate = myStructure == null;
            if (shouldCreate) {
                initStructure();
            }

            r.run();
// fixme: compat
//            if (shouldCreate) {
//                TreeState.createFrom(my State.treeState).applyTo(myTree);
//            }
        });

        //        if (isUnitTestMode()) {
/*        if (myProject.isInitialized()  *//* myProject.isDisposed() *//*) {
            if (myStructure != null) {
                r.run();
            }
            return;
        }*/
    }

    private void initStructure() {
        myStructure = new RestServiceStructure(myProject,myProjectsManager,myTree);

    }

    /**
     * 监听项目controller 方法变化
     */
    private void listenForProjectsChanges() {
        //todo :
    }


}
